<?php
declare (strict_types=1);

namespace app\api\controller\v1;

use app\api\helpers\Tree;
use app\api\helpers\v1\traits\SearchDataForModel;
use app\api\model\v1\AdminLog;
use app\api\model\v1\Admins;
use app\api\model\v1\AuthGroup;
use app\api\model\v1\AuthRule;
use app\api\model\v1\GroupUserPivot;
use app\api\validate\v1\RoleValidate;
use app\BaseController;
use think\exception\ValidateException;
use think\Request;

class Role extends BaseController
{
    use SearchDataForModel;

    /**
     * @User: 刘海龙
     * @Date: 2021/9/22
     * @Time: 18:04
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 角色列表
     */
    public function roleList()
    {
        $data = AuthGroup::select();
        $name = $this->request->param('name', '');
        $type = $this->request->param('type', 'list');
        if (!empty($name) && $type == 'child') {
            $top = AuthGroup::where('pid', 0)
                ->where('name', 'like', '%' . $name . '%')->select()->toArray();
        }
        if (!empty($top) && $type == 'child') {
            halt(3);
            $res       = [];
            $parent_id = [];
            foreach ($top as $key => $val) {
                $res[]              = $val;
                $res[$key]['child'] = AuthRule::sortMenu($data, $val['id']);
                $parent_id[]        = $val['id'];
            }
            empty($name) ?: $down = AuthGroup::whereNotIn('pid', $parent_id)
                    ->where('name', 'like', '%' . $name . '%')->where('pid', '<>', 0)
                    ->select()->toArray();
            empty($down) ?: $res = array_merge($res, $down);
        } elseif (empty($name) && $type == 'child') {

            $res = $this->search(new AuthGroup(), [], $perPage = 200);

//            $res  = AuthRule::sortMenu($data, 0);
        } else {
            halt(2);
            $map[] = array('name', 'like', '%' . $this->request->param('name') . '%');
            $res = $this->search(new AuthGroup(), $map, $perPage = 200);
        }

        return $this->response($res);


//        $map = [];
//        if ($this->request->has('name') && !empty($this->request->param('name'))) {
//            $map[] = array('title', 'like', '%' . $this->request->param('name') . '%');
//        }
//        //获取每页显示的条数
//        $limit = $this->request->param('limit');
//        $data = AuthGroup::where($map)->paginate($limit)->each(function ($item, $key) {
//            $where = [];
//            if ($item['rules'] !== '*') {
//                $where[] = array('id', 'in', $item['rules']);
//            }
//            $res = AuthRule::where($where)
//                ->select()->toArray();
//
//            $item['child'] = AuthRule::sortMenu($res);
//            return $item;
//        });
//        return $this->response($data);
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/22
     * @Time: 9:55
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 保存角色
     */
    public function saveRole()
    {
        $id = $this->request->param('id', 0);
        try {
            $validator = $this->validate($this->request->param(),
                RoleValidate::rules($id),
                RoleValidate::msg());

            if ($validator) {
                if (intval($id) === 0) {
                    $role = new AuthGroup();
                } else {
//                    halt($user_has_role = GroupUserPivot::where('group_id', $id)->exists());
//                    if ($this->request->param('status') == 0 && $user_has_role = GroupUserPivot::where('group_id', $id)->exists()) {
//                        return $this->response(501, '该角色已绑定用户，不可禁用');
//                    }
                    $role = AuthGroup::find($id);
                }
                $role->pid = $this->request->param('pid', 0);
                $role->name = $this->request->param('name');
                $role->rules = $this->request->param('rules');
                $role->status = $this->request->param('status', 1);
                $role->save();
                //日志
                AdminLog::record(intval($id) === 0 ? '新增角色' : '编辑角色', $this->request->param(), $this->request->uid, $this->request->username);
                return $this->response();
            }
        } catch (ValidateException $exception) {
            return $this->response(403, $exception->getError());
        }
    }

    /**
     * @param $id
     * @param $role_id
     * @User: 刘海龙
     * @Date: 2021/9/22
     * @Time: 18:07
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 删除角色
     */
    public function delRole($id, $role_id)
    {
        if (intval($id) === 1) {
            return $this->response(403, '超级管理员,不能删除');
        }
        $res = AuthGroup::find($id);
        $res_arr = explode(',', $res->rules);
        $key = array_search($role_id, $res_arr);
        if ($key === false) {
            return $this->response(403, '未找到该权限');
        }
        array_splice($res_arr, $key, 1);
        $res->rules = implode(',', $res_arr);
        $res->save();
        //重新获取最新的数据展示
        $res = AuthRule::where('id', 'in', $res_arr)
            ->where(['status' => 1])
            ->select()->toArray();
        $data = AuthRule::sortMenu($res);
        return $this->response($data);

    }

    /**
     * @param $id
     * @User: 刘海龙
     * @Date: 2021/9/22
     * @Time: 18:08
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 删除角色组
     */
    public function groupDel($id)
    {
        $ids_array = explode(',', $id);
        foreach ($ids_array as $id) {
            if ($id == 1) {
                return $this->response(501, '管理员不可删除');
            }
            $has_user = GroupUserPivot::where('group_id', $id)->find();
            if ($has_user) {
                return $this->response(501, '该角色已绑定用户，不可删除');
            }
        }
        foreach ($ids_array as $id) {
           $res = AuthGroup::where(['pid'=>$id])->count();
            if ($res > 0){
                return $this->response(501, '该角色存在下级，不可删除');
            }
            AuthGroup::find($id)->force()->delete();
        }
        //日志
        AdminLog::record('删除角色组', $this->request->param(), $this->request->uid, $this->request->username);
        return $this->response();
    }

    /**
     * @param $id
     * @param $status
     * @User: 刘海龙
     * @Date: 2021/9/22
     * @Time: 18:10
     * @return \think\response\Json
     * 更新角色状态
     */
    public function updateRoleStatus($id, $status)
    {

        $data = [
            'id' => $id,
            'status' => $status
        ];
        if (intval($id) === 1) {
            return $this->response(403, '超级管理员,不能更改');
        }
        AuthGroup::update($data);
        //日志
        AdminLog::record('更新角色状态', $this->request->param(), $this->request->uid, $this->request->username);
        return $this->response();
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/23
     * @Time: 9:52
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 保存角色(中间表)
     */
    public function setRoleUserPivot(){
        $uid = $this->request->param('uid');
        $group_id= $this->request->param('group_id');
        $group_id = explode(',', $group_id);
        $user = Admins::find($uid);
        if (is_null($user)) {
            return $this->response(404, '此用户不存在');
        }
        // 删除中间表数据
        $user->roles()->detach();
        $user->roles()->attach($group_id);

        AdminLog::record('保存角色', $this->request->param(), $this->request->uid, $this->request->username);
        return $this->response();
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/23
     * @Time: 9:53
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 获取所有角色列表
     */
    public function roleInfoList(){
        $res = AuthGroup::select()->toArray();
        return $this->response($res);
    }

    /**
     * @User: 刘海龙
     * @Date: 2021/9/23
     * @Time: 16:51
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * 根据当前获取父级的菜单权限
     */
    public function allotMenuAuth(){
        $id = $this->request->param("id");
        $pid = $this->request->param("pid");
        $parentGroupModel = AuthGroup::find($pid);
        $currentGroupModel = null;
        if ($id) {
            $currentGroupModel = AuthGroup::find($id);
        }
        if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
            $id = $id ? $id : null;
            $ruleList = $this->collection(AuthRule::order('id', 'asc')->select())->toArray();

            //读取父类角色所有节点列表
            $parentRuleList = [];
            if (in_array('*', explode(',', $parentGroupModel->rules))) {
                $parentRuleList = $ruleList;
            } else {
                $parentRuleIds = explode(',', $parentGroupModel->rules);
                foreach ($ruleList as $k => $v) {
                    if (in_array($v['id'], $parentRuleIds)) {
                        $parentRuleList[] = $v;
                    }
                }
            }
            $childrenGroupIds = $this->auth->getChildrenGroupIds(true,$this->request->uid);

            $ruleTree = new Tree();
            $groupTree = new Tree();
            //当前所有正常规则列表
            $ruleTree->init($parentRuleList);
            //角色组列表
            $groupTree->init($this->collection(AuthGroup::where('id', 'in', $childrenGroupIds)->select())->toArray());

            //读取当前角色下规则ID集合
            $adminRuleIds = $this->auth->getRuleIds($this->request->uid);
            //是否是超级管理员
            $superadmin = $this->auth->isSuperAdmin($this->request->uid);
            //当前拥有的规则ID集合
            $currentRuleIds = $id ? explode(',', $currentGroupModel->rules) : [];
            if (!$id || !in_array($pid, $childrenGroupIds) || !in_array($pid, $groupTree->getChildrenIds($id, true))) {
                $parentRuleList = $ruleTree->getTreeList($ruleTree->getTreeArray(0), 'name');
                $hasChildrens = [];
                foreach ($parentRuleList as $k => $v) {
                    if ($v['haschild']) {
                        $hasChildrens[] = $v['id'];
                    }
                }
                $parentRuleIds = array_map(function ($item) {
                    return $item['id'];
                }, $parentRuleList);
                $nodeList = [];
                foreach ($parentRuleList as $k => $v) {

                    if (!$superadmin && !in_array($v['id'], $adminRuleIds)) {
                        continue;
                    }
                    if ($v['pid'] && !in_array($v['pid'], $parentRuleIds)) {
                        continue;
                    }
                    $state = array('selected' => in_array($v['id'], $currentRuleIds) && !in_array($v['id'], $hasChildrens));
                    $nodeList[] = array('id' => $v['id'], 'pid' => $v['pid'], 'title' => $v['title']);
                 //   $nodeList[] = array('id' => $v['id'], 'parent' => $v['pid'] ? $v['pid'] : '#', 'text' => __($v['title']), 'type' => 'menu', 'state' => $state);
                }

                $res = AuthRule::sortMenu($nodeList);
                return $this->response($res);
            }
        }
    }
}
